<?php


namespace app\api\controller;

class CardApp extends ApiBase
{
	public function check()
	{
		$validate = \think\Validate::make(["card" => "require"], ["card.require" => "卡密 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$card = findCardCaseSensitive("app_card_user", ["appid" => $this->project["id"], "card" => $this->input["card"]]);
		if (empty($card)) {
			$this->response(10043, "卡密不存在");
		}
		if ($card["disable"] == 1) {
			$this->response(10044, "卡密被禁用");
		}
		\think\Db::startTrans();
		try {
			$date = date("Y-m-d H:i:s");
			$user_safe_config = json_decode($this->project["user_safe_config"], true);
			$machine_code_binding_top_limit = !empty($user_safe_config["machine_code_binding_top_limit"]) ? $user_safe_config["machine_code_binding_top_limit"] : \app\common\model\DefaultConfig::UserMachineCodeBindingTopLimit;
			if ($card["machine_code_binding_top_limit"] != 0) {
				$machine_code_binding_top_limit = $card["machine_code_binding_top_limit"];
			}
			if (!empty($user_safe_config["machine_code_verify"])) {
				if (!isset($this->input["machine_code"]) || $this->input["machine_code"] == "") {
					$this->response(10045, "当前缺少机器码参数machine_code");
				}
				if (!verifyMachineCode($this->input["machine_code"], $card["machine_code"], $machine_code_binding_top_limit)) {
					$this->response(10046, "机器码校验失败");
				}
			}
			if ($card["status"] == 0) {
				$endtime = \app\common\helper\Time::computing_time($card["time_type"], $card["time_value"], time());
				\app\common\server\StatisticsData::increases($this->project["id"], \app\common\model\AppData::CardAppUserActivation, 1);
				if ($card["agent_id"]) {
					$appBinding = \think\Db::name("app_agent_binding")->where(["agent_id" => $card["agent_id"]])->find();
					if ($appBinding && $appBinding["card_disable"]) {
						$this->response(10047, "此卡由于上级相关权限被关闭,已作废不可使用");
					}
					\app\common\server\StatisticsData::increases($this->project["id"], \app\common\model\AppData::CardAppAgentUserActivation, 1, $card["agent_id"]);
				}
				\think\Db::name("app_card_user")->where(["id" => $card["id"]])->update(["status" => 1, "usetime" => time()]);
				$logid = \app\api\common\card\Finance::set($card, "endtime", $endtime, 0, "首次使用卡密激活", \app\common\model\CardAppModel::UserCardEndTimeLogSourceUseActivate);
				$card["endtime"] = $endtime;
				$card["usetime"] = time();
			}
			if (empty($this->project["user_verify_mode"])) {
				if ($card["endtime"] < time()) {
					$this->response(10048, "卡密已到期");
				}
			} else {
				if ($this->project["user_verify_mode"] == 1) {
				} elseif ($this->project["user_verify_mode"] == 2) {
				}
			}
			$user_machine_code = getUserMachineCodeList($card["machine_code"]);
			if (!empty($this->input["machine_code"]) && !in_array($this->input["machine_code"], $user_machine_code) && count($user_machine_code) < $machine_code_binding_top_limit) {
				$user_machine_code[] = $this->input["machine_code"];
				\think\Db::name("app_card_user")->where(["id" => $card["id"]])->update(["machine_code" => json_encode($user_machine_code, JSON_UNESCAPED_UNICODE)]);
			}
			$today = \think\helper\Time::today();
			if ($card["acttime"] < $today[0]) {
				\app\common\server\StatisticsData::increases($this->project["id"], \app\common\model\AppData::CardAppUserActive, 1);
			}
			$online_machine_upper_limit = $user_safe_config["online_machine_upper_limit"] ?? \app\common\model\DefaultConfig::UserOnlineMachineUpperLimit;
			if ($card["online_machine_upper_limit"] != 0) {
				$online_machine_upper_limit = $card["online_machine_upper_limit"];
			}
			$minimum_active_time = time() - ($user_safe_config["online_time_difference"] ?? \app\common\model\DefaultConfig::AppUserHeartbeatInterval);
			$machine_code = $this->input["machine_code"] ?? "";
			$current_online_list = \think\Db::name("app_card_user_login_machine")->where([["appid", "=", $this->project["id"]], ["uid", "=", $card["id"]], ["active_time", ">", $minimum_active_time], ["machine_code", "<>", $machine_code], ["force_offline_status", "=", 0], ["token_status", "=", 0]])->order("login_time", "asc")->select();
			if ($online_machine_upper_limit <= count($current_online_list) && $online_machine_upper_limit > 0) {
				if (empty($user_safe_config["online_machine_upper_limit_login_scheme"])) {
					$this->response(10049, "当前无法登录,已在其他设备登录");
				} else {
					if ($user_safe_config["online_machine_upper_limit_login_scheme"] == 1) {
						\think\Db::name("app_card_user_login_machine")->where(["id" => $current_online_list[0]["id"]])->update(["token_status" => 1, "token" => ""]);
					}
				}
			}
			$login_machine = \think\Db::name("app_card_user_login_machine")->where(["appid" => $this->project["id"], "uid" => $card["id"], "machine_code" => $machine_code])->find();
			$binding_ip_list = json_decode($card["binding_ip_list"], true) ?? [];
			$machine_binding_ip_list = $login_machine ? json_decode($login_machine["binding_ip_list"], true) ?? [] : [];
			if (!empty($user_safe_config["ip_verify"])) {
				$ip_binding_top_limit = $user_safe_config["ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserIpUpperLimit;
				if ($card["ip_binding_top_limit"] != 0) {
					$ip_binding_top_limit = $card["ip_binding_top_limit"];
				}
				$machine_ip_binding_top_limit = $user_safe_config["machine_ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserMachineIpBindingTopLimit;
				if ($card["machine_ip_binding_top_limit"] != 0) {
					$machine_ip_binding_top_limit = $card["machine_ip_binding_top_limit"];
				}
				if ($ip_binding_top_limit > 0 && !in_array($this->client_ip, $binding_ip_list) && $ip_binding_top_limit <= count($binding_ip_list)) {
					$this->response(10050, "您的IP:" . $this->client_ip . "没有在绑定IP列表内无法进行登录");
				} else {
					if (!in_array($this->client_ip, $binding_ip_list)) {
						$binding_ip_list[] = $this->client_ip;
					}
				}
				if ($machine_ip_binding_top_limit > 0 && !in_array($this->client_ip, $machine_binding_ip_list) && $machine_ip_binding_top_limit <= count($machine_binding_ip_list)) {
					$this->response(10051, "您的IP:" . $this->client_ip . "没有在本设备绑定IP列表内无法进行登录");
				} else {
					if (!in_array($this->client_ip, $machine_binding_ip_list)) {
						$machine_binding_ip_list[] = $this->client_ip;
					}
				}
			}
			\think\Db::name("app_card_user")->where(["id" => $card["id"]])->update(["acttime" => time(), "force_offline_status" => 0, "binding_ip_list" => json_encode($binding_ip_list)]);
			$token = GenerateToken(["id" => $card["id"], "startTime" => time()]);
			if ($login_machine) {
				$token_info = json_decode(hex2bin($login_machine["token"]), true);
				if (!checkUserTokenInvalid($user_safe_config, $token_info) && empty($user_safe_config["token_update_mechanism"]) && $token_info) {
					$token = $login_machine["token"];
				}
				\think\Db::name("app_card_user_login_machine")->where(["id" => $login_machine["id"]])->update(["ip" => $this->client_ip, "token" => $token, "machine_info" => $this->input["machine_info"] ?? "", "login_time" => time(), "active_time" => time(), "token_status" => 0, "force_offline_status" => 0, "binding_ip_list" => json_encode($machine_binding_ip_list)]);
			} else {
				\think\Db::name("app_card_user_login_machine")->insert(["appid" => $this->project["id"], "uid" => $card["id"], "machine_code" => $machine_code, "machine_info" => $this->input["machine_info"] ?? "", "ip" => $this->client_ip, "token" => $token, "login_time" => time(), "active_time" => time(), "binding_ip_list" => json_encode($machine_binding_ip_list)]);
			}
			$surplusTime = $card["endtime"] - time();
			$data = ["cardInfo" => ["id" => $card["id"], "card" => $card["card"], "time_type" => $card["time_type"], "time_value" => $card["time_value"], "addtime" => $card["addtime"], "endtime" => $card["endtime"], "usetime" => $card["usetime"], "status" => $card["status"], "private_data" => (object) get_app_user_private_data($this->project, $card["private_data"], "user"), "token" => $token, "point" => $card["point"], "remarks" => $card["remarks"]], "surplusTime" => ["second" => $surplusTime, "minute" => intval($surplusTime % 86400 % 3600 / 60), "hour" => intval($surplusTime % 86400 / 3600), "day" => intval($surplusTime / 86400)], "expireTimeStr" => date("Y-m-d H:i:s", $card["endtime"])];
			\think\Db::commit();
			$this->response(Code::success, "登录成功", $data);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function revise_private_data()
	{
		$validate = \think\Validate::make(["card" => "require", "field" => "require", "content" => "require"], ["card.require" => "卡密 不能为空！", "field.require" => "字段名 不能为空！", "content.require" => "修改内容 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $card) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\CardAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $card);
		}
		\think\Db::startTrans();
		try {
			$user_private_data_config = json_decode($this->project["user_private_data_config"], true);
			$private_data = json_decode($card["private_data"], true);
			$field_exist = false;
			$current_field_config = [];
			if ($user_private_data_config) {
				foreach ($user_private_data_config as $private_data_item) {
					if ($private_data_item["field"] == $this->input["field"]) {
						$field_exist = true;
						$current_field_config = $private_data_item;
						break;
					}
				}
			}
			if ($field_exist) {
				if (empty($current_field_config["authority"]["revise"])) {
					$this->response(10065, "没有修改权限");
				}
				$original_content = $private_data[$this->input["field"]] ?? "";
				$private_data[$this->input["field"]] = $this->input["content"];
				\think\Db::name("app_card_user")->where(["id" => $card["id"]])->update(["private_data" => json_encode($private_data, JSON_FORCE_OBJECT)]);
				\think\Db::commit();
				$this->response(Code::success, "修改成功", ["original_content" => $original_content, "new_content" => $this->input["content"]]);
			} else {
				$this->response(10066, "字段不存在");
			}
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function self_service_unbinding()
	{
		$validate = \think\Validate::make(["card" => "require"], ["card.require" => "卡密 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$user_safe_config = json_decode($this->project["user_safe_config"], true);
		$verify = new \app\api\common\entity\CardAppUserVerify();
		list($verify_code, $card) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $card);
		}
		if (!getUserMachineCodeList($card["machine_code"])) {
			$this->response(10067, "当前未绑定机器码无需解绑");
		}
		\think\Db::startTrans();
		try {
			if (!empty($user_safe_config["self_service_unbinding"]["open"])) {
				if (!empty($user_safe_config["self_service_unbinding"]["interval"]) && $card["self_service_unbinding_time"] > time()) {
					$this->response(10068, "解绑时间未到");
				}
				$self_service_unbinding_time = time() + $user_safe_config["self_service_unbinding"]["interval"];
				if (!empty($user_safe_config["self_service_unbinding"]["frequency_limit_type"])) {
					list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($user_safe_config["self_service_unbinding"]["frequency_limit_type"]);
					$count = \think\Db::name("app_card_user_unbinding_log")->where([["card_id", "=", $card["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end]])->count();
					if ($user_safe_config["self_service_unbinding"]["frequency_limit_value"] <= $count) {
						$this->response(10069, "当前时间不可解绑");
					}
				}
				if (!empty($user_safe_config["self_service_unbinding"]["deduction_time"])) {
					if ($card["endtime"] - $user_safe_config["self_service_unbinding"]["deduction_time"] < time()) {
						$this->response(10070, "解绑失败,您的剩余时长不足以解绑扣除");
					} else {
						$logid = \app\api\common\card\Finance::set($card, "endtime", $card["endtime"] - $user_safe_config["self_service_unbinding"]["deduction_time"], 0, "自助解绑扣除时长", \app\common\model\CardAppModel::UserCardEndTimeLogSourceSelfUnbinding);
					}
				}
				$update = ["machine_code" => "", "self_service_unbinding_time" => $self_service_unbinding_time, "force_offline_status" => 1];
				if (!empty($user_safe_config["self_service_unbinding"]["clear_binding_ip_list"])) {
					$update["binding_ip_list"] = "";
				}
				\think\Db::name("app_card_user")->where(["id" => $card["id"]])->update($update);
				if (!empty($user_safe_config["self_service_unbinding"]["clear_machine_binding_ip_list"])) {
					\think\Db::name("app_card_user_login_machine")->where(["uid" => $card["id"]])->update(["binding_ip_list" => ""]);
				}
				\think\Db::name("app_card_user_unbinding_log")->insert(["appid" => $card["appid"], "card_id" => $card["id"], "time" => time(), "source" => \app\common\model\CardAppModel::UserUnBindingLogSourceSelfUnbinding]);
				\think\Db::commit();
				$this->response(Code::success, "解绑成功", []);
			} else {
				$this->response(10071, "未开启自助解绑功能");
			}
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public static function verify_user($project, $apiInfo, $apiConfig, $input, \app\api\common\entity\CardAppUserVerify $verify) : array
	{
		try {
			$user_safe_config = json_decode($project["user_safe_config"], true);
			if (isset($user_safe_config["token_verify_open"]) && $user_safe_config["token_verify_open"]) {
				$verify->setToken(true);
			}
			if (isset($user_safe_config["machine_code_verify"]) && $user_safe_config["machine_code_verify"]) {
				$verify->setMachineCode(true);
			} else {
				$verify->setMachineCode(false);
			}
			if (isset($user_safe_config["ip_verify"]) && $user_safe_config["ip_verify"]) {
				$verify->setIp(true);
			}
			if ($apiConfig && !empty($apiConfig["verify_user_token"])) {
				if ($apiConfig["verify_user_token"] === 1) {
					$verify->setToken(true);
				} elseif ($apiConfig["verify_user_token"] === 2) {
					$verify->setToken(false);
				}
			}
			if ($apiConfig && !empty($apiConfig["verify_machine_code"])) {
				if ($apiConfig["verify_machine_code"] === 1) {
					$verify->setMachineCode(true);
				} elseif ($apiConfig["verify_machine_code"] === 2) {
					$verify->setMachineCode(false);
				}
			}
			if ($apiConfig && !empty($apiConfig["verify_ip"])) {
				if ($apiConfig["verify_ip"] === 1) {
					$verify->setIp(true);
				} elseif ($apiConfig["verify_ip"] === 2) {
					$verify->setIp(false);
				}
			}
			if ($apiInfo["id"] == 8) {
				if (empty($user_safe_config["self_service_unbinding"]["verify_user_token"])) {
					$verify->setToken(false);
				} else {
					$verify->setToken(true);
				}
				if (empty($user_safe_config["self_service_unbinding"]["verify_original_machine"])) {
					$verify->setMachineCode(false);
				} else {
					$verify->setMachineCode(true);
				}
				if (empty($user_safe_config["self_service_unbinding"]["verify_ip"])) {
					$verify->setIp(false);
				} else {
					$verify->setIp(true);
				}
			}
			if ($apiInfo["id"] == 67) {
				$verify->setToken(true);
			}
			$card = findCardCaseSensitive("app_card_user", ["appid" => $input["appid"], "card" => $input["card"] ?? ""]);
			if (empty($card)) {
				return [10052, "卡密不存在"];
			}
			if ($card["disable"] == 1) {
				return [10053, "卡密被禁用"];
			}
			if ($verify->isStatus()) {
				if ($card["status"] == 0) {
					return [10054, "卡密未使用"];
				}
			}
			if ($verify->isEndtime()) {
				if ($card["endtime"] < time()) {
					return [10055, "卡密已到期"];
				}
			}
			if ($apiInfo["verify_user"] !== 0) {
				if ($verify->isMachineCode()) {
					if (!isset($input["machine_code"]) || $input["machine_code"] == "") {
						return [10056, "当前缺少机器码参数machine_code"];
					}
					$machine_code_binding_top_limit = !empty($user_safe_config["machine_code_binding_top_limit"]) ? $user_safe_config["machine_code_binding_top_limit"] : \app\common\model\DefaultConfig::UserMachineCodeBindingTopLimit;
					if ($card["machine_code_binding_top_limit"] != 0) {
						$machine_code_binding_top_limit = $card["machine_code_binding_top_limit"];
					}
					if (!verifyMachineCode($input["machine_code"], $card["machine_code"], $machine_code_binding_top_limit)) {
						return [10057, "机器码校验失败"];
					}
				}
				$login_machine = \think\Db::name("app_card_user_login_machine")->where(["appid" => $project["id"], "uid" => $card["id"], "machine_code" => $input["machine_code"] ?? ""])->find();
				if ($verify->isToken()) {
					if (empty($login_machine) || empty($input["user_token"]) || $login_machine["token"] != $input["user_token"]) {
						return [10058, "用户token校验失败"];
					}
					if ($login_machine["token_status"] == 1) {
						return [10059, "已在其他设备登录"];
					}
					if ($login_machine["token_status"] == 3) {
						return [10060, "登录状态失效"];
					}
					$token_info = json_decode(hex2bin($input["user_token"]), true);
					if ($card["force_offline_status"] == 1 || $login_machine["force_offline_status"] == 1) {
						return [10061, "您被强制下线"];
					}
					if (checkUserTokenInvalid($user_safe_config, $token_info)) {
						return [10062, "用户token失效"];
					}
				}
				if ($verify->isIp()) {
					$binding_ip_list = json_decode($card["binding_ip_list"], true) ?? [];
					$machine_binding_ip_list = $login_machine ? json_decode($login_machine["binding_ip_list"], true) ?? [] : [];
					$ip_binding_top_limit = $user_safe_config["ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserIpUpperLimit;
					if ($card["ip_binding_top_limit"] != 0) {
						$ip_binding_top_limit = $card["ip_binding_top_limit"];
					}
					$machine_ip_binding_top_limit = $user_safe_config["machine_ip_binding_top_limit"] ?? \app\common\model\DefaultConfig::UserMachineIpBindingTopLimit;
					if ($card["machine_ip_binding_top_limit"] != 0) {
						$machine_ip_binding_top_limit = $card["machine_ip_binding_top_limit"];
					}
					if ($ip_binding_top_limit > 0 && !in_array(client_ip, $binding_ip_list)) {
						return [10063, "绑定ip验证失败,您的IP:" . client_ip . "没有在绑定IP列表内"];
					}
					if ($machine_ip_binding_top_limit > 0 && !in_array(client_ip, $machine_binding_ip_list)) {
						return [10064, "绑定ip验证失败,您的IP:" . client_ip . "没有在本设备绑定IP列表内"];
					}
				}
			}
			return [Code::success, $card, $login_machine ?? []];
		} catch (\Exception $e) {
			return [Code::fail, "系统错误:" . $e->getMessage()];
		}
	}
	public function get_card_info()
	{
		$validate = \think\Validate::make(["card" => "require"], ["card.require" => "卡密 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$card = findCardCaseSensitive("app_card_user", ["appid" => $this->project["id"], "card" => $this->input["card"]]);
		if (empty($card)) {
			$this->response(10072, "卡密不存在");
		}
		if (isset($this->input["update_active"])) {
			$verify = new \app\api\common\entity\CardAppUserVerify();
			$verify->setToken(true);
			$verify->setEndtime(false);
			list($verify_code, $card) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
			if ($verify_code !== Code::success) {
				$this->response($verify_code, $card);
			}
			\think\Db::name("app_card_user")->where(["id" => $card["id"]])->update(["acttime" => time()]);
			$machine_code = $this->input["machine_code"] ?? "";
			$login_machine = \think\Db::name("app_card_user_login_machine")->where(["appid" => $this->project["id"], "uid" => $card["id"], "machine_code" => $machine_code])->find();
			if ($login_machine) {
				\think\Db::name("app_card_user_login_machine")->where(["id" => $login_machine["id"]])->update(["active_time" => time()]);
			}
		}
		$surplusTime = $card["endtime"] - time();
		$data = ["cardInfo" => ["id" => $card["id"], "card" => $card["card"], "time_type" => $card["time_type"], "time_value" => $card["time_value"], "addtime" => $card["addtime"], "endtime" => $card["endtime"], "usetime" => $card["usetime"], "status" => $card["status"], "point" => $card["point"], "remarks" => $card["remarks"]], "surplusTime" => ["second" => $surplusTime, "minute" => intval($surplusTime % 86400 % 3600 / 60), "hour" => intval($surplusTime % 86400 / 3600), "day" => intval($surplusTime / 86400)], "expireTimeStr" => date("Y-m-d H:i:s", $card["endtime"])];
		$this->response(Code::success, "获取成功", $data);
	}
	public function increase_or_decrease_time()
	{
		$validate = \think\Validate::make(["card" => "require", "type" => "require|in:0,1", "value" => "require|number", "remarks" => "require"], ["card.require" => "卡密 不能为空！", "type.require" => "操作类型 不能为空！", "value.require" => "操作数量 不能为空！", "remarks.require" => "备注 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$verify = new \app\api\common\entity\CardAppUserVerify();
		$verify->setStatus(true);
		list($verify_code, $card) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $card);
		}
		$card_app_config = json_decode($this->project["card_app_config"], true);
		if (empty($card_app_config["time_config"]["api_increase_open"]) && $this->input["type"] == 0) {
			$this->response(10073, "未开启增加功能");
		}
		if (empty($card_app_config["time_config"]["api_reduce_open"]) && $this->input["type"] == 1) {
			$this->response(10074, "未开启减少功能");
		}
		if (!empty($card_app_config["time_config"]["api_increase_maximum"]) && $this->input["value"] > $card_app_config["time_config"]["api_increase_maximum"] && $this->input["type"] == 0) {
			$this->response(10075, "增加数量不能超过" . $card_app_config["time_config"]["api_increase_maximum"]);
		}
		if (!empty($card_app_config["time_config"]["api_increase_minimum"]) && $this->input["value"] < $card_app_config["time_config"]["api_increase_minimum"] && $this->input["type"] == 0) {
			$this->response(10076, "增加数量不能小于" . $card_app_config["time_config"]["api_increase_minimum"]);
		}
		if (!empty($card_app_config["time_config"]["api_reduce_maximum"]) && $this->input["value"] > $card_app_config["time_config"]["api_reduce_maximum"] && $this->input["type"] == 1) {
			$this->response(10077, "减少数量不能超过" . $card_app_config["time_config"]["api_reduce_maximum"]);
		}
		if (!empty($card_app_config["time_config"]["api_reduce_minimum"]) && $this->input["value"] < $card_app_config["time_config"]["api_reduce_minimum"] && $this->input["type"] == 1) {
			$this->response(10078, "减少数量不能小于" . $card_app_config["time_config"]["api_reduce_minimum"]);
		}
		if (!empty($card_app_config["time_config"]["api_increase_frequency_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($card_app_config["time_config"]["api_increase_frequency_limit_type"]);
			$count = \think\Db::name("app_card_user_finance_log")->where([["user_id", "=", $card["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "endtime"], ["source", "=", \app\common\model\CardAppModel::UserCardEndTimeLogSourceClientApi]])->count();
			if ($card_app_config["time_config"]["api_increase_frequency_limit_value"] <= $count) {
				$this->response(10079, "周期次数已上限");
			}
		}
		if (!empty($card_app_config["time_config"]["api_increase_quantity_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($card_app_config["time_config"]["api_increase_quantity_limit_type"]);
			$sum = \think\Db::name("app_card_user_finance_log")->where([["user_id", "=", $card["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "endtime"], ["source", "=", \app\common\model\CardAppModel::UserCardEndTimeLogSourceClientApi]])->sum("number");
			if ($sum + $this->project["value"] > $card_app_config["time_config"]["api_increase_quantity_limit_value"]) {
				$this->response(10080, "周期数量已上限");
			}
		}
		if ($card["time_type"] == \app\common\model\CardTimeType::Perpetual) {
			$this->response(10081, "不支持已是永久时长的用户");
		}
		\think\Db::startTrans();
		try {
			if ($this->input["type"] == 0) {
				$endtime = $card["endtime"] + $this->input["value"];
			} else {
				$endtime = $card["endtime"] - $this->input["value"];
			}
			$logid = \app\api\common\card\Finance::set($card, "endtime", $endtime, $this->input["type"], "客户端API操作,备注:" . $this->input["remarks"], \app\common\model\CardAppModel::UserCardEndTimeLogSourceClientApi);
			\think\Db::commit();
			$this->response(Code::success, "操作成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function logout()
	{
		$validate = \think\Validate::make(["card" => "require"], ["card.require" => "卡密 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$verify = new \app\api\common\entity\CardAppUserVerify();
		$verify_user = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
		$verify_code = $verify_user[0];
		$card = $verify_user[1];
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $card);
		}
		$login_machine = $verify_user[2];
		\think\Db::startTrans();
		try {
			\think\Db::name("app_card_user_login_machine")->where(["id" => $login_machine["id"]])->update(["token_status" => 3]);
			\think\Db::commit();
			$this->response(Code::success, "操作成功");
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function disable()
	{
		$validate = \think\Validate::make(["card" => "require"], ["card.require" => "卡密 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$verify = new \app\api\common\entity\CardAppUserVerify();
		list($verify_code, $card) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, $verify);
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $card);
		}
		\think\Db::name("app_card_user")->where(["id" => $card["id"]])->update(["disable" => 1]);
		$this->response(Code::success, "操作成功");
	}
	public function increase_or_decrease_points()
	{
		$validate = \think\Validate::make(["card" => "require", "type" => "require|in:0,1", "value" => "require|number", "remarks" => "require"], ["card.require" => "用户ID 不能为空！", "type.require" => "操作类型 不能为空！", "value.require" => "操作数量 不能为空！", "remarks.require" => "备注 不能为空！"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		list($verify_code, $user) = self::verify_user($this->project, $this->apiInfo, $this->apiConfig, $this->input, new \app\api\common\entity\CardAppUserVerify());
		if ($verify_code !== Code::success) {
			$this->response($verify_code, $user);
		}
		$card_app_config = json_decode($this->project["card_app_config"], true);
		if (empty($card_app_config["point_config"]["api_increase_open"]) && $this->input["type"] == 0) {
			$this->response(10082, "未开启增加功能");
		}
		if (empty($card_app_config["point_config"]["api_reduce_open"]) && $this->input["type"] == 1) {
			$this->response(10083, "未开启减少功能");
		}
		if (!empty($card_app_config["point_config"]["api_increase_maximum"]) && $this->input["value"] > $card_app_config["point_config"]["api_increase_maximum"] && $this->input["type"] == 0) {
			$this->response(10084, "增加数量不能超过" . $card_app_config["point_config"]["api_increase_maximum"]);
		}
		if (!empty($card_app_config["point_config"]["api_increase_minimum"]) && $this->input["value"] < $card_app_config["point_config"]["api_increase_minimum"] && $this->input["type"] == 0) {
			$this->response(10085, "增加数量不能小于" . $card_app_config["point_config"]["api_increase_minimum"]);
		}
		if (!empty($card_app_config["point_config"]["api_reduce_maximum"]) && $this->input["value"] > $card_app_config["point_config"]["api_reduce_maximum"] && $this->input["type"] == 1) {
			$this->response(10086, "减少数量不能超过" . $card_app_config["point_config"]["api_reduce_maximum"]);
		}
		if (!empty($card_app_config["point_config"]["api_reduce_minimum"]) && $this->input["value"] < $card_app_config["point_config"]["api_reduce_minimum"] && $this->input["type"] == 1) {
			$this->response(10087, "减少数量不能小于" . $card_app_config["point_config"]["api_reduce_minimum"]);
		}
		if (!empty($card_app_config["point_config"]["api_increase_frequency_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($card_app_config["point_config"]["api_increase_frequency_limit_type"]);
			$count = \think\Db::name("app_card_user_finance_log")->where([["user_id", "=", $user["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "point"], ["source", "=", \app\common\model\CardAppModel::UserPointLogSourceClientApi]])->count();
			if ($card_app_config["point_config"]["api_increase_frequency_limit_value"] <= $count) {
				$this->response(10088, "周期次数已上限");
			}
		}
		if (!empty($card_app_config["point_config"]["api_increase_quantity_limit_type"]) && $this->input["type"] == 0) {
			list($time_start, $time_end) = \app\common\helper\Time::get_cycle_time($card_app_config["point_config"]["api_increase_quantity_limit_type"]);
			$sum = \think\Db::name("app_card_user_finance_log")->where([["user_id", "=", $user["id"]], ["time", ">=", $time_start], ["time", "<=", $time_end], ["field", "=", "point"], ["source", "=", \app\common\model\CardAppModel::UserPointLogSourceClientApi]])->sum("number");
			if ($sum + $this->project["value"] > $card_app_config["point_config"]["api_increase_quantity_limit_value"]) {
				$this->response(10089, "周期数量已上限");
			}
		}
		if ($this->input["type"] == 1 && $user["point"] < $this->input["value"]) {
			$this->response(10090, "当前数量不足以减少扣除");
		}
		\think\Db::startTrans();
		try {
			$logid = \app\api\common\card\Finance::set($user, "point", $this->input["value"], $this->input["type"], "客户端API操作,备注:" . $this->input["remarks"], \app\common\model\CardAppModel::UserPointLogSourceClientApi);
			\think\Db::commit();
			$this->response(Code::success, "操作成功", ["original_point" => $user["point"], "new_point" => \think\Db::name("app_card_user")->where(["id" => $user["id"]])->value("point", 0)]);
		} catch (\Exception $e) {
			\think\Db::rollback();
			$this->response(Code::error, $e->getMessage());
		}
	}
	public function create_renewal_order()
	{
		$validate = \think\Validate::make(["pay_type" => "require|in:1,2,3", "type" => "require", "value" => "require|number|>=:1", "user" => "require"], ["pay_type.require" => "请选择支付方式", "type.require" => "开通/续费类型 不能为空", "value.require" => "开通/续费面值 不能为空", "user.require" => "开通/续费卡密 不能为空"]);
		if (!$validate->check($this->input)) {
			$this->response(Code::fail, $validate->getError());
		}
		$result = \app\common\service\AppCardBuy::createRenewalOrder($this->input);
		if ($result["code"] != 1) {
			$this->response(Code::fail, $result["msg"]);
		}
		$pay_url = getsiteurl() . "/index/buy/pay/order_id/" . $result["data"]["id"];
		if (!empty($this->input["return_url"])) {
			$pay_url .= "?return_url=" . urlencode($this->input["return_url"]);
		}
		$this->response(Code::success, $result["msg"], array_merge($result["data"], ["pay_url" => $pay_url]));
	}
}